package com.xjve.framework.hibernate.jpa;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.core.RepositoryInformation;
import org.springframework.data.repository.core.support.RepositoryFactoryInformation;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Repository注册表，自动注册Repository
 */
@Component
public class RepositoryRegistry implements BeanPostProcessor, ApplicationContextAware {
    private static final Logger log = LoggerFactory.getLogger(RepositoryRegistry.class);
    private static final Map<Class<?>, JpaRepository<?, ?>> REPOSITORY_MAP = new ConcurrentHashMap<>();
    private ApplicationContext applicationContext;

    @Value("${xjve-framework.fast-search:true}")
    private boolean autoRegisterEnabled;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        // 检查是否为RepositoryFactoryInformation类型的Bean
        if (autoRegisterEnabled && bean instanceof RepositoryFactoryInformation) {
            processRepositoryFactoryInformation((RepositoryFactoryInformation<?, ?>) bean, beanName);
        }
        return bean;
    }

    /**
     * 处理RepositoryFactoryInformation类型的Bean
     */
    private void processRepositoryFactoryInformation(RepositoryFactoryInformation<?, ?> factoryInfo, String beanName) {
        try {
            // 从RepositoryFactoryInformation获取Repository信息
            RepositoryInformation repositoryInfo = factoryInfo.getRepositoryInformation();
            if (repositoryInfo != null) {
                Class<?> repositoryInterface = repositoryInfo.getRepositoryInterface();

                // 检查是否有NoRepositoryRegister注解
                if (hasNoRepositoryRegisterAnnotation(repositoryInterface)) {
                    log.info("Skipping registration for repository {} as it is marked @NoRepositoryRegister", beanName);
                    return;
                }

                // 获取实体类类型
                Class<?> domainType = repositoryInfo.getDomainType();
                if (domainType != null) {
                    // 获取实际的Repository实例
                    JpaRepository<?, ?> repository = (JpaRepository<?, ?>) applicationContext.getBean(repositoryInterface);
                    REPOSITORY_MAP.put(domainType, repository);
                    log.info("Registered repository for entity: {} with repository interface: {}",
                            domainType.getSimpleName(), repositoryInterface.getSimpleName());
                }
            }
        } catch (Exception e) {
            log.warn("Failed to process repository factory information for bean: " + beanName, e);
        }
    }

    /**
     * 检查Repository接口是否被NoRepositoryRegister注解标记
     */
    private boolean hasNoRepositoryRegisterAnnotation(Class<?> repositoryInterface) {
        return repositoryInterface.isAnnotationPresent(NoRepositoryRegister.class);
    }

    /**
     * 获取实体类对应的Repository
     */
    @SuppressWarnings("unchecked")
    public static <T, ID> JpaRepository<T, ID> getRepository(Class<T> entityClass) {
        JpaRepository<T, ID> repository = (JpaRepository<T, ID>) REPOSITORY_MAP.get(entityClass);
        if (repository == null) {
            log.warn("No repository found for entity: {}", entityClass.getSimpleName());
        }
        return repository;
    }
}
